#include <QCoreApplication>
#include "qglobal.h"
#include <iostream>
//多继承的类的对象的成员在RAM中的分布

class A
{
public:
    A(int pub_tmp=0):
        m_a(pub_tmp){ m_pri_a = 100; }
    int m_a;
    void add()
    {
        m_a++;
    }
    virtual void show(void)
    {
        printf("call A::show() %d, %d\n", m_a, m_pri_a);
    }
    virtual void show_a(void)
    {
        printf("call A::show_a()\n");
    }

private:
    int m_pri_a;

};

class B
{
 public:
    B(int pub_tmp=0):
        m_b(pub_tmp){m_pri_b = 200;  }
    int m_b;
    void add()
    {
        m_b++;
    }
    virtual void show(void)
    {
        printf("call B::show() %d, %d\n",m_b, m_pri_b);
    }
    virtual void show_b(void)
    {
        printf("call B::show_b()\n");
    }

private:
    int m_pri_b;
};

class C:public A,public B
{
public:
    C(int pub_tmp=0):
        A(pub_tmp),
        B(pub_tmp),
        m_c(pub_tmp){ m_pri_c = 300; }
    int m_c;
    void add()
    {
        m_c++;
    }
    virtual void show(void)
    {
        printf("call C::show() %d, %d\n",m_c, m_pri_c);
    }
    virtual void show_c(void)
    {
        printf("call C::show_c()\n");
    }
private:
    int m_pri_c;
};

class D:public C
{
public:
    D(int pub_tmp=0):
        C(pub_tmp),
        m_d(pub_tmp){ m_pri_d = 400; }
    int m_d;
    virtual void show(void)
    {
        printf("call D::show() %d, %d\n",m_d, m_pri_d);
    }
    virtual void show_d(void)
    {
        printf("call D::show_d()\n");
    }
private:
    int m_pri_d;
};


typedef void (*pFunc)(void);

int main()
{
    printf("start\n");
    printf("sizeof(int) = %d\n", sizeof(int));


    C obj_c(3);
    A *pA_c = (A*)&obj_c;
    B *pB_c = (B*)&obj_c;
    C *pC_c = &obj_c;

    printf("pA_c = %d\n", (int)pA_c);//A、C虚表的地址的地址
    printf("pB_c = %d\n", (int)pB_c);//B虚表的地址的地址
    printf("pC_c = %d\n", (int)pC_c);//A、C虚表的地址的地址

    printf("&obj_c.m_a = %d\n", (int)&obj_c.m_a);
    printf("&obj_c.m_b = %d\n", (int)&obj_c.m_b);
    printf("&obj_c.m_c = %d\n", (int)&obj_c.m_c);


    printf("obj_c.m_pri_a = %d\n", *((&obj_c.m_a)+1));//可以读到A的私有成员m_pri_a
    printf("obj_c.m_pri_b = %d\n", *((&obj_c.m_b)+1));//可以读到B的私有成员m_pri_b
    printf("obj_c.m_pri_b = %d\n", *(int *)((char*)(pC_c)+sizeof(A)+4+4));//可以读到B的私有成员m_pri_b


    pFunc pShow;
    int *addr_v_table_AC = (int*)*(int*)pA_c;//获取对象c的A虚表和C虚表的地址(见下文注释)
    pShow = (pFunc)*addr_v_table_AC;//从虚表中取出第1个虚函数的地址
    pShow();
    pShow = (pFunc)*(addr_v_table_AC+1);//从虚表中取出第2个虚函数的地址
    pShow();
    pShow = (pFunc)*(addr_v_table_AC+2);//从虚表中取出第3个虚函数的地址
    pShow();

    int *addr_v_table_B = (int*)*(int*)pB_c;//获取对象c的B虚表的地址
    pShow = (pFunc)*addr_v_table_B;//从虚表中取出第1个虚函数的地址
    pShow();
    pShow = (pFunc)*(addr_v_table_B+1);//从虚表中取出第2个虚函数的地址
    pShow();

    D obj_d(4);

    A *pA_d = (A*)&obj_d;
    B *pB_d = (B*)&obj_d;
    C *pC_d = (C*)&obj_d;
    D *pD_d = &obj_d;

    printf("pA_d = %d\n", (int)pA_d);//
    printf("pB_d = %d\n", (int)pB_d);//
    printf("pC_d = %d\n", (int)pC_d);//
    printf("pD_d = %d\n", (int)pD_d);//

    printf("v_table_A exec:\n");//
    int *addr_v_table_A = (int*)*(int*)pA_d;
    pShow = (pFunc)*addr_v_table_A;//从虚表中取出第1个虚函数的地址
    pShow();
    pShow = (pFunc)*(addr_v_table_A+1);//从虚表中取出第2个虚函数的地址
    pShow();
    pShow = (pFunc)*(addr_v_table_A+2);//从虚表中取出第3个虚函数的地址
    pShow();
    pShow = (pFunc)*(addr_v_table_A+3);//从虚表中取出第4个虚函数的地址
    pShow();

    printf("v_table_B exec:\n");//
    addr_v_table_B = (int*)*(int*)pB_d;
    pShow = (pFunc)*addr_v_table_B;//从虚表中取出第1个虚函数的地址
    pShow();
    pShow = (pFunc)*(addr_v_table_B+1);//从虚表中取出第2个虚函数的地址
    pShow();



    pA_d->show();
    pB_d->show();
    pC_d->show();
    pD_d->show();




    return 0;
}







